/**
 * Copyright (C) 2011 Andrew C. Love (DNC) <dnc.app.sup@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dnc.cloak.framework.reflect;

import java.util.Map;

import org.apache.log4j.Logger;

import com.dnc.cloak.framework.util.dataconvert.DataConverter;

public class ReflectionMethodParameter {
	
    private static final Logger log = Logger.getLogger(ReflectionMethodParameter.class);
    
    private static final String TIME = "Time";
    private static final String TIMESTAMP = "Timestamp";
    private static final String DATE = "Date";
    private static final String BYTE = "Byte";
    private static final String DOUBLE = "Double";
    private static final String FLOAT = "Float";
    private static final String LONG = "Long";
    private static final String SHORT = "Short";
    private static final String BOOLEAN = "Boolean";
    private static final String STRING = "String";
    private static final String CHARACTER = "Character";
    private static final String INTEGER = "Integer";
    private static final String OBJECT = "Object";
    private static final String CONSTANT = "constant";
    
    private Object constantValue = null;
    private String parmType = null;
    private String parmName = null;
    private String className = null;
    private String primitive = null;

    
    public ReflectionMethodParameter(String parmTypeArg, String parmNameArg, String classNameArg, String maskArg, String stringValueArg, String primitiveArg) throws ReflectionException {
    	
        parmType = parmTypeArg;
        parmName = parmNameArg;
        className = classNameArg;
        primitive = primitiveArg;
        
        if(parmType.equalsIgnoreCase(CONSTANT)) { 
            constantValue = getMethodParameterConstantValue(parmTypeArg, parmNameArg, classNameArg, maskArg, stringValueArg);
        }
        
    }
    
    public Object getParameterValue(Map<String,Object> storage) {
    	
        if(parmType.equalsIgnoreCase(CONSTANT)) {
            return constantValue;
        }
        else{
            return storage.get(parmName);
        }
        
    }
    
    public Class<?> getParameterClass()throws ReflectionException {
    	
        try {
            Class<?> localclass = Class.forName(className);
            if (primitive.equalsIgnoreCase("true")){
                localclass = getPrimitiveClass(localclass);
            }
            return localclass;
        }
        catch (Exception ex) {
            throw new ReflectionException(ex);
        }
    }

    private Class<?> getPrimitiveClass(Class<?> localClass) throws ReflectionException {
    	
        if (localClass == Integer.class){
            return Integer.TYPE;                   
        }     
        else if (localClass == Character.class){
            return Character.TYPE;                        
        }
        else if (localClass == Boolean.class){
            return Boolean.TYPE;                        
        }
        else if (localClass == Short.class){
            return Short.TYPE;                        
        }
        else if (localClass == Long.class){
            return Long.TYPE;                        
        }
        else if (localClass == Float.class){
            return Float.TYPE;                        
        }
        else if (localClass == Double.class){
            return Double.TYPE;                        
        }
        else if (localClass == Byte.class){
            return Byte.TYPE;                        
        }
        else{
            return localClass;
        }
       
    }
    
    
    private Object getMethodParameterConstantValue(String parmType, String parmName, String className, String mask, String value) throws ReflectionException {

    	Object returnValue = null;
            
        try {
            if (className.indexOf(OBJECT)>=0){
                returnValue = new Object();                        
            }                        
            else if (className.indexOf(INTEGER)>=0){
                returnValue = DataConverter.getInteger(value);                        
            }                        
            else if (className.indexOf(CHARACTER)>=0){
                returnValue = DataConverter.getCharacter(value);                        
            }                        
            else if (className.indexOf(STRING)>=0){
                returnValue = value;                        
            }                        
            else if (className.indexOf(BOOLEAN)>=0){
                returnValue = DataConverter.getBoolean(value);                        
            }          
            else if (className.indexOf(SHORT)>=0){
                returnValue = DataConverter.getShort(value);                        
            }          
            else if (className.indexOf(LONG)>=0){
                returnValue = DataConverter.getLong(value);                        
            }          
            else if (className.indexOf(FLOAT)>=0){
                returnValue = DataConverter.getFloat(value);                        
            }          
            else if (className.indexOf(DOUBLE)>=0){
                returnValue = DataConverter.getDouble(value);                        
            }          
            else if (className.indexOf(BYTE)>=0){
                returnValue = DataConverter.getByte(value);                        
            }          
            else if (className.indexOf(DATE)>=0){
                returnValue = DataConverter.getDate(value,mask);                        
            }          
            else if (className.indexOf(TIMESTAMP)>=0){
                returnValue = DataConverter.getSqlTimestamp(value);                        
            }
            else if (className.indexOf(TIME)>=0){
                returnValue = DataConverter.getSqlTime(value);                        
            }          
            else{
                throw new ReflectionException(parmName + ":Unsupported Class for parameter transform:" + className );
            }            
            log.debug("parameter:" + className + ":"+ value);
        }
        catch (Exception ex) {
            throw new ReflectionException(ex);
        }
        
        return returnValue;
        
    }   
    
}